#ifndef xpack_dumb_init_by
#define xpack_dumb_init_by
#pragma push_macro("xuser")
#undef  xuser
#define xuser mixc::dumb_init_by::inc
#include"define/base_type.hpp"
#include"dumb/move.hpp"
#include"macro/xexport.hpp"
#include"macro/xforward.hpp"
#include"meta/has_constructor.hpp"
#pragma pop_macro("xuser")

namespace mixc::dumb_init_by::origin{
    template<class a0_t = void, class ... args_t> struct init_by;

    template<class a0_t, class ... args_t>
    struct init_by : init_by<args_t...>{
        constexpr init_by(a0_t & first, args_t && ... rest) :
            init_by<args_t...>(xforward(rest)...), arg(first) {}

        constexpr init_by(a0_t && first, args_t && ... rest) :
            init_by<args_t...>(xforward(rest)...), arg(first) {}

        template<class object_t, class ... argsx_t>
        object_t * make(object_t * this_ptr, argsx_t && ... list) const {
            return init_by<args_t...>::make(this_ptr, xforward(list)..., inc::move(arg));
        }

        template<class object_t, class ... argsx_t>
        static constexpr bool test() {
            return inc::has_constructor<object_t, void(argsx_t &&...)>;
        }

    private:
        mutable a0_t arg;
    };

    template<>
    struct init_by<void>{
        constexpr init_by(){}

        template<class object_t, class ... argsx_t>
        object_t * make(object_t * this_ptr, argsx_t && ... list) const {
            return xnew(this_ptr) object_t(xforward(list)...);
        }

        template<class object_t, class ... argsx_t>
        static constexpr bool test() {
            return inc::has_constructor<object_t, void(argsx_t &&...)>;
        }
    };

    constexpr init_by<> default_init_by{};

    template<class object_t, class init_by_t>
    concept can_init = init_by_t::template test<object_t>();
}

#endif

xexport_space(mixc::dumb_init_by::origin)